package sh.orm;

import lombok.Setter;
import sh.base.aop.util.ReflectUtil;
import sh.base.config.ConfigManager;
import sh.orm.cache.CacheConfig;
import sh.orm.cache.CacheManager;
import sh.orm.cache.DefaultCacheManager;
import sh.orm.cache.redis.RedisCacheManager;
import sh.orm.cache.redis.RedisConnection;

import java.util.Properties;

/**
 * 产生session的工厂,单例模式
 * @author lqq
 * @date 2019/1/28
 */
public class SessionFactory {

    private ThreadLocal<Session> sessionThreadLocal = new ThreadLocal<>();

    private static SessionFactory sessionFactory;

    /** 二级缓存管理器  ，提供set方法是为了动态替换缓存管理器，同时测试默认缓存管理器和redis缓存管理器 ，TODO 待优化，用更好的方式动态替换 */
    @Setter
    private CacheManager cacheManager;

    /** 二级缓存的配置 */
    private CacheConfig cacheConfig;

    /** 配置管理器 */

    ConfigManager configManager;

    /**
     * 构造方法，
     */
    public SessionFactory(){
        //orm中也需要管理配置
        //orm 中应该提供怎样的配置供用户使用，如果二级缓存开启，那么初始化二级缓存 TODO
        configManager = ConfigManagerInitiator.getInstance().getConfigManager();

        initCacheManger();
    }

    /**
     * 未来使用spring管理bean工厂
     * @return
     */
    @Deprecated
    public static SessionFactory getInstance(){
        if(sessionFactory != null){
            return sessionFactory;
        }else {
            synchronized (SessionFactory.class){
                sessionFactory = new SessionFactory();


            }
        }
        return sessionFactory;
    }

    /**
     * 初始化二级缓存管理器
     */
    private void initCacheManger(){
        String className = configManager.getProperties().getProperty(OrmConst.CACHE_CACHEMANAGER_CLASSNAME);

        if(DefaultCacheManager.class.getName().equals(className)){
            cacheManager = new DefaultCacheManager();
            //TODO 按照配置进行初始化，这里先不做操作
            return;
        }
        if(RedisCacheManager.class.getName().equals(className)){
            String host = configManager.getProperties().getProperty(OrmConst.CACHE_REDIS_HOST);
            int port = Integer.valueOf(configManager.getProperties().getProperty(OrmConst.CACHE_REDIS_PORT));
            String password = configManager.getProperties().getProperty(OrmConst.CACHE_REDIS_PASSWORD, null);
            RedisConnection redisConnection = new RedisConnection(host, port, password);
            cacheManager = new RedisCacheManager(redisConnection);
            return;
        }
        throw new OrmException("没有对应的缓存管理器:" + className);
    }


    public Session createSession(){
        return new Session(this, cacheManager);
    }

    /**
     * 返回一个session，如果没有则创建，如果已经有了，返回当前的。
     * @return
     */
    public Session getSession(){
        Session session = sessionThreadLocal.get();
        if(session == null){
            session = new Session(this, cacheManager);
            sessionThreadLocal.set(session);
        }
        return  session;
    }

    public void removeSession(){
        sessionThreadLocal.remove();
    }

}
